<!DOCTYPE HTML>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <title>SlickGrid example 5: Collapsing</title>
  <link rel="stylesheet" href="../slick.grid.css" type="text/css" />
  <link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.24.custom.css" type="text/css" />
  <link rel="stylesheet" href="examples.css" type="text/css" />
  <style>
    .cell-title {
      font-weight: bold;
    }

    .cell-effort-driven {
      text-align: center;
    }

    .toggle {
      height: 9px;
      width: 9px;
      display: inline-block;
    }

    .toggle.expand {
      background: url(../images/expand.gif) no-repeat center center;
    }

    .toggle.collapse {
      background: url(../images/collapse.gif) no-repeat center center;
    }
  </style>
</head>

<body>
  <table width="100%">
    <tr>
      <td valign="top" width="80%">
        <div id="myGrid" style="width:600px;height:500px;"></div>
      </td>
      <td valign="top">
        <h2>Demonstrates:</h2>
        <ul>
          <li>implementing expand/collapse as a filter for DataView</li>
        </ul>

        <h2>View Source:</h2>
        <ul>
          <li><A href="https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example5-collapsing.html"
              target="_sourcewindow"> View the source for this example on Github</a></li>
        </ul>
      </td>
    </tr>
  </table>

  <script src="../lib/firebugx.js"></script>

  <script src="../lib/jquery-1.7.min.js"></script>
  <script src="../lib/jquery-ui-1.8.24.custom.min.js"></script>
  <script src="../lib/jquery.event.drag-2.2.js"></script>

  <script src="../slick.core.js"></script>
  <script src="../slick.formatters.js"></script>
  <script src="../slick.editors.js"></script>
  <script src="../slick.grid.js"></script>
  <script src="../slick.dataview.js"></script>

  <script>
    function requiredFieldValidator(value) {
      if (value == null || value == undefined || !value.length) {
        return { valid: false, msg: "This is a required field" };
      } else {
        return { valid: true, msg: null };
      }
    }


    var TaskNameFormatter = function (row, cell, value, columnDef, dataContext) {
      value = value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
      var spacer = "<span style='display:inline-block;height:1px;width:" + (15 * dataContext["indent"]) + "px'></span>";
      var idx = dataView.getIdxById(dataContext.id);
      if (data[idx + 1] && data[idx + 1].indent > data[idx].indent) {
        if (dataContext._collapsed) {
          return spacer + " <span class='toggle expand'></span>&nbsp;" + value;
        } else {
          return spacer + " <span class='toggle collapse'></span>&nbsp;" + value;
        }
      } else {
        return spacer + " <span class='toggle'></span>&nbsp;" + value;
      }
    };

    var dataView;
    var grid;
    var data = [];
    var groups = [[{ "group": "D", "name": "设计", "expend": true }, { "group": "S", "name": "进度", "expend": true }, { "group": "G", "name": "其他", "expend": true }]];
    var columns = [
      { id: "title", name: "Title", group: ["D"], field: "title", width: 220, cssClass: "cell-title", formatter: TaskNameFormatter, editor: Slick.Editors.Text, validator: requiredFieldValidator },
      { id: "duration", name: "Duration", group: ["S"], field: "duration", editor: Slick.Editors.Text },
      { id: "%", name: "% Complete", group: ["S"], field: "percentComplete", width: 80, resizable: false, formatter: Slick.Formatters.PercentCompleteBar, editor: Slick.Editors.PercentComplete },
      { id: "start", name: "Start", group: ["G"], field: "start", minWidth: 60, editor: Slick.Editors.Date },
      { id: "finish", name: "Finish", group: ["G"], field: "finish", minWidth: 120, editor: Slick.Editors.Date },
      { id: "effort-driven", name: "Effort Driven", group: ["G"], width: 200, minWidth: 20, maxWidth: 200, cssClass: "cell-effort-driven", field: "effortDriven", formatter: Slick.Formatters.Checkmark, editor: Slick.Editors.Checkbox, cannotTriggerInsert: true }
    ];

    var options = {
      editable: true,
      enableAddRow: true,
      enableCellNavigation: true,
      asyncEditorLoading: false,
      frozenColumn: 0,
      headerGroups: groups,
      showHeaderRow: false
    };

    var percentCompleteThreshold = 0;
    var searchString = "";

    function myFilter(item) {
      if (item["percentComplete"] < percentCompleteThreshold) {
        return false;
      }

      if (searchString != "" && item["title"].indexOf(searchString) == -1) {
        return false;
      }

      if (item.parent != null) {
        var parent = data[item.parent];

        while (parent) {
          if (parent._collapsed || (parent["percentComplete"] < percentCompleteThreshold) || (searchString != "" && parent["title"].indexOf(searchString) == -1)) {
            return false;
          }

          parent = data[parent.parent];
        }
      }

      return true;
    }

    function percentCompleteSort(a, b) {
      return a["percentComplete"] - b["percentComplete"];
    }

    $(function () {
      var indent = 0;
      var parents = [];

      // prepare the data
      for (var i = 0; i < 1000; i++) {
        var d = (data[i] = {});
        var parent;

        if (Math.random() > 0.8 && i > 0) {
          indent++;
          parents.push(i - 1);
        } else if (Math.random() < 0.3 && indent > 0) {
          indent--;
          parents.pop();
        }

        if (parents.length > 0) {
          parent = parents[parents.length - 1];
        } else {
          parent = null;
        }

        d["id"] = "id_" + i;
        d["indent"] = indent;
        d["parent"] = parent;
        d["title"] = "Task " + i;
        d["duration"] = "5 days";
        d["percentComplete"] = Math.round(Math.random() * 100);
        d["start"] = "01/01/2009";
        d["finish"] = "01/05/2009";
        d["effortDriven"] = (i % 5 == 0);
      }

      // initialize the model
      dataView = new Slick.Data.DataView({ inlineFilters: true });
      dataView.beginUpdate();
      dataView.setItems(data);
      dataView.setFilter(myFilter);
      dataView.endUpdate();

      // initialize the grid
      grid = new Slick.Grid("#myGrid", dataView, columns, options);

      grid.onCellChange.subscribe(function (e, args) {
        dataView.updateItem(args.item.id, args.item);
      });

      grid.onAddNewRow.subscribe(function (e, args) {
        var item = {
          "id": "new_" + (Math.round(Math.random() * 10000)),
          "indent": 0,
          "title": "New task",
          "duration": "1 day",
          "percentComplete": 0,
          "start": "01/01/2009",
          "finish": "01/01/2009",
          "effortDriven": false
        };
        $.extend(item, args.item);
        dataView.addItem(item);
      });

      grid.onClick.subscribe(function (e, args) {
        if ($(e.target).hasClass("toggle")) {
          var item = dataView.getItem(args.row);
          if (item) {
            if (!item._collapsed) {
              item._collapsed = true;
            } else {
              item._collapsed = false;
            }

            dataView.updateItem(item.id, item);
          }
          e.stopImmediatePropagation();
        }
      });

      // wire up model events to drive the grid
      dataView.onRowCountChanged.subscribe(function (e, args) {
        grid.updateRowCount();
        grid.render();
      });

      dataView.onRowsChanged.subscribe(function (e, args) {
        grid.invalidateRows(args.rows);
        grid.render();
      });

      var h_runfilters = null;

      // wire up the slider to apply the filter to the model
      $("#pcSlider").slider({
        "range": "min",
        "slide": function (event, ui) {
          Slick.GlobalEditorLock.cancelCurrentEdit();

          if (percentCompleteThreshold != ui.value) {
            window.clearTimeout(h_runfilters);
            h_runfilters = window.setTimeout(dataView.refresh, 10);
            percentCompleteThreshold = ui.value;
          }
        }
      });

      // wire up the search textbox to apply the filter to the model
      $("#txtSearch").keyup(function (e) {
        Slick.GlobalEditorLock.cancelCurrentEdit();

        // clear on Esc
        if (e.which == 27) {
          this.value = "";
        }

        searchString = this.value;
        dataView.refresh();
      })
    })
  </script>
</body>

</html>